home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / comm / misc / DigiCam.lha / src / Goodie / seeserial.c
C/C++ Source or Header  |  1999-07-14  |  12KB  |  356 lines

  1. /* seeserial.c (c) 1999 by Volker Remuß, remuss@cs.tu-berlin.de          */
  2. /*                                                                       */
  3. /* For LINUX/UNIX. Can be used to link a camera connection through       */
  4. /* another computer to listen to the protocol. The complete known        */
  5. /* protocol is watched and interpreted.                                  */
  6. /* Since the algorithm is very simple you only see every package if the  */
  7. /* next package in the other direction is send.                          */
  8. /* I used this to spy out the communication between the windowssoftware  */
  9. /* and the camera.                                                       */
  10. /*                                                                       */
  11. /* If you want to do this, too. Don't forget to fix the serial speed to  */
  12. /* 19200 bps. No other speed is possible, because changes in speed are   */
  13. /* not recognized by seeserial.                                          */
  14.  
  15.  
  16.  
  17. #include <sys/stat.h>
  18. #include <sys/types.h>
  19. #include <fcntl.h>
  20. #include <termios.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24.  
  25.  
  26. #define HOST   "/dev/ttyS1"
  27. #define KAMERA "/dev/ttyS2"
  28. #define BPS B19200
  29.  
  30. int s1fd=-1, s2fd=-1;                  // Serial1 and Serial2 FDs 
  31. struct termios oldtio1, oldtio2;
  32.  
  33. void myexit(int ret)
  34. {
  35.   if (s1fd != -1)
  36.   {
  37.     tcsetattr(s1fd, TCSANOW, &oldtio1);
  38.     close(s1fd);
  39.   }
  40.  
  41.   if (s2fd != -1)
  42.   {
  43.     tcsetattr(s2fd, TCSANOW, &oldtio2);
  44.     close(s2fd);
  45.   }
  46.  
  47.   exit (ret);
  48. }
  49.  
  50. void openser()
  51. {
  52.   struct termios newtio1, newtio2;
  53.   
  54.   // Open Serial Port 1
  55.   s1fd = open(HOST, O_RDWR | O_NOCTTY); // read/write
  56.   if (s1fd < 0) {perror(HOST); myexit(-1); }
  57.  
  58.   tcgetattr(s1fd, &oldtio1); // save current settings of serial port 1
  59.  
  60.   // Init Serial Port 1
  61.   bzero(&newtio1, sizeof(newtio1));
  62.   newtio1.c_cflag = BPS | CS8 | CLOCAL | CREAD;
  63.   newtio1.c_iflag = IGNPAR | IGNBRK;
  64.   newtio1.c_oflag = 0; 
  65.   newtio1.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */
  66.   newtio1.c_cc[VTIME] = 1;   /* inter-character timer  */
  67.   newtio1.c_cc[VMIN]  = 0;   /* blocking read until x chars received */
  68.   
  69.   tcflush(s1fd, TCIOFLUSH);
  70.   tcsetattr(s1fd,TCSANOW,&newtio1);
  71.  
  72.  
  73.   // Open Serial Port 2
  74.   s2fd = open(KAMERA, O_RDWR | O_NOCTTY); // non-blocking read/write
  75.   if (s2fd < 0) {perror(KAMERA); myexit(-1); }
  76.  
  77.   tcgetattr(s2fd, &oldtio2); // save current settings of serial port 2
  78.   
  79.   // Init Serial Port 1
  80.   bzero(&newtio2, sizeof(newtio2));
  81.   newtio2.c_cflag = BPS | CS8 | CLOCAL | CREAD;
  82.   newtio2.c_iflag = IGNPAR | IGNBRK;
  83.   newtio2.c_oflag = 0; 
  84.   newtio2.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */
  85.   newtio2.c_cc[VTIME] = 1;   /* inter-character timer  */
  86.   newtio2.c_cc[VMIN]  = 0;   /* blocking read until x chars received */
  87.   
  88.   tcflush(s2fd, TCIOFLUSH);
  89.   tcsetattr(s2fd,TCSANOW,&newtio2);
  90.  
  91. }
  92.  
  93. void cryout (unsigned char *buf, int cnt, char *string)
  94. // output of complete buffer in hex and as far as possible as human readable
  95. {
  96.   int i, nochncnt=0;
  97.   unsigned char nochnbuf[100];
  98.  
  99.   if (cnt) printf("\nReceived from %s:\n", string);
  100.   else return;
  101.  
  102.   for (i=0; i < cnt; i++)
  103.   {
  104.     printf("%2hx ", buf[i]);
  105.  
  106.     if ((buf[i] >= ' ') && (buf[i] <='~'))     // readable character? if not write a . instead
  107.       nochnbuf[nochncnt++] = buf[i];
  108.     else
  109.       nochnbuf[nochncnt++] = '.';
  110.  
  111.     if ((nochncnt) > 11)
  112.     {
  113.       nochnbuf[nochncnt] = 0;
  114.       printf("     %s\n", nochnbuf);
  115.       nochncnt = 0;
  116.     }
  117.   }
  118.  
  119.   if (nochncnt)
  120.   {
  121.     nochnbuf[nochncnt] = '\0';
  122.     for (i=(12-nochncnt); i > 0; i--) printf("   ");
  123.     printf("     %s\n", nochnbuf);
  124.     nochncnt = 0;
  125.   }
  126. }
  127.  
  128. void interpret(unsigned char *buf, int cnt)
  129. {
  130.   if (cnt)
  131.   {
  132.     if (cnt > 1)
  133.     {
  134.       if (buf[0] == 0x06)
  135.     {
  136.       printf("Acknowledged and \n");
  137.       buf++;
  138.       cnt--;
  139.     }
  140.       if (buf[0] == 0x15)
  141.     {
  142.       printf("Not Acknowledged and\n");
  143.       buf++;
  144.       cnt--;
  145.     }
  146.     }
  147.  
  148.     switch (cnt)
  149.     {
  150.       case 1:
  151.         switch (buf[0])
  152.         {
  153.           case 0x00: printf("Initialisation of camera\n"); break;
  154.       case 0x05: printf("Action completed\n"); break; 
  155.           case 0x06: printf("Acknowledged\n"); break;
  156.           case 0x15: printf("Not Acknowledged or camera response to init\n"); break;
  157.           case 0x11: printf("Unable to Execute Command\n"); break;
  158.           case 0xff: printf("Termnination - Camera did an idlereset\n"); break;
  159.           default:   printf("Unknown one byte packet\n"); break;
  160.         }
  161.         break;
  162.  
  163.      case 2:
  164.        if ((buf[0] == 0x06) && (buf[2] == 0x05))
  165.          printf("\n Acknowledged and Action Completed\n");
  166.        else
  167.          printf("Unknown two bytes packet\n");
  168.        break;
  169.  
  170.      default:
  171.        switch (buf[0])
  172.        {
  173.          case 0x02: printf("Data packet that is not last in sequence\n");
  174.                     printf("Sequence Nr.: %d\n Datalength: %d\n", buf[1], (buf[2] | (buf[3] << 8)));
  175.                     break;
  176.  
  177.          case 0x03: printf("Data packet that is last in sequence\n");
  178.                     printf("Sequence Nr.: %d\n Datalength: %d\n", buf[1], (buf[2] | (buf[3] << 8)));
  179.                     break;
  180.  
  181.          case 0x1b: printf("Command Packet - ");
  182.                     switch (buf[1])
  183.                     {
  184.                       case 0x43: printf("just an ordinary one\n"); break;
  185.                       case 0x53: printf("the first in session\n"); break;
  186.                       default:   printf("of unknown type\n"); break;
  187.                     }
  188.  
  189.                     printf("Length of command and parameter is: %d\nCommandtype: ", (buf[2] | (buf[3] << 8)));
  190.                     switch (buf[4])
  191.                     {
  192.                       case 0: printf("Set value of integer register"); break;
  193.                       case 1: printf("Read value of integer register"); break;
  194.                       case 2: printf("Take action unrelated to registers: "); break;
  195.                       case 3: printf("Set value of vdata register"); break;
  196.                       case 4: printf("Read value of vdata register"); break;
  197.                      default: printf("Unknown type of command"); break;
  198.                     }
  199.                     
  200.                     if (buf[4] != 2)
  201.                     {
  202.                       printf("\n Register No. %d Type: ", buf[5]);
  203.                       switch (buf[5])
  204.                       {
  205.                         case  1: printf("Resolution"); break;
  206.                         case  2: printf("Clock"); break;
  207.                         case  3: printf("Shutter Speed"); break;
  208.                         case  4: printf("Current Frame Number"); break;
  209.                         case  5: printf("Aperture"); break;
  210.                         case  6: printf("Color Mode"); break;
  211.                         case  7: printf("Flash Mode"); break; 
  212.                         case 10: printf("No. of frames taken"); break;
  213.                         case 11: printf("No. of frames left"); break;
  214.                         case 12: printf("Length of current frame"); break;
  215.                         case 13: printf("Length of current thumbnail"); break;
  216.                         case 14: printf("Current frame JFIF data"); break;
  217.                         case 15: printf("Current thumbnail JFIF data"); break;
  218.                         case 16: printf("Battery Capacity"); break;
  219.                         case 17: printf("Communication Speed"); break;
  220.                         case 19: printf("Brightness + Contrast"); break;
  221.                         case 20: printf("White balance"); break;
  222.                         case 22: printf("Camera I.D."); break;
  223.                         case 23: printf("Autoshut on host timer"); break;
  224.                         case 24: printf("Autoshut in field timer"); break;
  225.                         case 25: printf("Serial No."); break;
  226.                         case 26: printf("Version"); break;
  227.                         case 27: printf("Model"); break;
  228.                         case 28: printf("Available Memory left"); break;
  229.                         case 29: printf("Upload image JFIF"); break;
  230.                         case 30: printf("LED"); break;
  231.                         case 32: printf("Used before uploading image"); break;
  232.                         case 33: printf("Lens mode"); break;
  233.                         case 35: printf("LCD brightness"); break;
  234.                         case 38: printf("LCD autoshut timer"); break;
  235.                         case 39: printf("Protection state of current frame"); break;
  236.                         case 41: printf("LCD date format"); break;
  237.                         case 44: printf("Audiodata"); break;
  238.                         case 46: printf("Camera summary data"); break;
  239.                         case 47: printf("Picture summary data"); break;
  240.                         case 48: printf("Manufaacturer"); break;
  241.                         case 70: printf("Exp.meter"); break;
  242.                         case 72: printf("Bitmap"); break;
  243.                         default: printf("Unknown No. %d", buf[5]); break;
  244.                       }
  245.                     }
  246.                     else
  247.                     {
  248.                       switch (buf[5])
  249.                       {
  250.                         case  0: printf("Erase last picture"); break;
  251.                         case  1: printf("Erase all pictures"); break;
  252.                         case  2: printf("Take picture"); break;
  253.                         case  4: printf("Finish session immediately"); break;
  254.                         case  5: printf("Take preview snapshot"); break;
  255.                         case  7: printf("Erase current frame"); break;
  256.                         case  9: printf("Set protection of current frame"); break;
  257.                         case 11: printf("Store freshly uploaded image inbto NVRAM"); break;
  258.                         default: printf("Unkown command %d", buf[5]); break;
  259.                       }
  260.                     }
  261.                     printf("\n");
  262.                     break;
  263.  
  264.           default:  printf("Unknown packet type\n");
  265.                     break;
  266.        }
  267.     }
  268.   }
  269. }
  270.                     
  271.  
  272.  
  273.  
  274. void main(void)
  275. {
  276.   int rd1, rd2;    // readcounter
  277.   unsigned char buf1[2100], buf2[2100];        // Readin - Throwout Buffer for both serials 
  278.   unsigned char outbuf[100000];                    // Buffer for screenoutput to collect uninterrupted chunks of same input data
  279.   int outcnt=0;                           // used to organize outbuf
  280.   int lastinput=0;                         // last serial that got an input 
  281.  
  282.  
  283.   openser();
  284.  
  285.   while (1)
  286.   {
  287.     if ((rd1=read(s1fd, buf1, 2100)) == -1)  // error ?
  288.     {
  289.       perror("While reading Host");
  290.       exit(-1);
  291.     }
  292.  
  293.     if (rd1)                                 // got input 
  294.     {
  295.       if ((write(s2fd, buf1, rd1)) != rd1)   // foward to other port - error?
  296.       {
  297.           perror("While writing Kamera");
  298.           exit(-1);
  299.       }
  300.  
  301.       if ((lastinput != 1) || ((outcnt+rd1) > 100000))    // different port than last input?
  302.       {
  303.         cryout(outbuf, outcnt, HOST);     // yes -> dump buffer to screen
  304.         interpret(outbuf, outcnt);
  305.         lastinput = 1;
  306.         outcnt = 0;
  307.       }
  308.                                          // no -> append to outbuffer
  309.       /*
  310.       if ((outcnt + rd1) > 100000)
  311.       {
  312.         fprintf(stderr, "Outputbuffer for screendump overflowed\n");
  313.         myexit(-1);
  314.       }
  315.       */
  316.       memcpy(outbuf+outcnt, buf1, rd1);
  317.       outcnt += rd1;
  318.     }
  319.  
  320.     if ((rd2=read(s2fd, buf2, 2100)) == -1)  // error ?
  321.     {
  322.       perror("While reading Kamera");
  323.       exit(-1);
  324.     }
  325.  
  326.      if (rd2)                             // output to other port
  327.     {
  328.       if ((write(s1fd, buf2, rd2)) != rd2)
  329.       {
  330.         perror("While writing Host");
  331.           exit(-1);
  332.       }
  333.  
  334.       if ((lastinput != 2) || ((outcnt+rd2 > 100000)))   // different port than last input?
  335.       {
  336.         cryout(outbuf, outcnt, KAMERA);     // yes -> dump buffer to screen
  337.         interpret(outbuf, outcnt);
  338.         lastinput = 2;
  339.         outcnt = 0;
  340.       }
  341.                                              // append to outbuffer
  342.       /*
  343.       if ((outcnt + rd2) > 100000)
  344.       {
  345.         fprintf(stderr, "Outputbuffer for screendump overflowed\n");
  346.         myexit(-1);
  347.       }
  348.       */
  349.       memcpy(outbuf+outcnt, buf2, rd2);
  350.       outcnt += rd2;
  351.     }
  352.   }
  353.  
  354.   myexit(0);
  355. }
  356.